package com.xbongbong.saas.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.domain.entity.PaasAppEntity;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasStageEntity;
import com.xbongbong.paas.domain.entity.StageProcessEntity;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.DateEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.EnableEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.SharePermissionHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.thread.LogThreadPoolBeanConfig;
import com.xbongbong.paas.model.PaasAppModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.StageProcessModel;
import com.xbongbong.paas.pojo.dto.ApplicationListDTO;
import com.xbongbong.paas.pojo.vo.ApplicationListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.helper.PageHelper;
import com.xbongbong.paas.toolbox.util.CompareUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.PageHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.BaseVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.ShareConditionBusinessFieldEnum;
import com.xbongbong.pro.enums.ShareRuleFilterConditionEnum;
import com.xbongbong.pro.enums.ShareSupportFormEnum;
import com.xbongbong.pro.enums.errorcodes.SharePermissionErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formexplain.pojo.FieldAndLogicPojo;
import com.xbongbong.pro.formexplain.pojo.LogicPojo;
import com.xbongbong.pro.formexplain.pojo.vo.ExplainFilterConditionVO;
import com.xbongbong.pro.knowledge.base.pojo.OptionalRangePojo;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.pro.service.toolbox.statistic.help.FormHelp;
import com.xbongbong.pro.sharepermission.pojo.LinkInfoMidPojo;
import com.xbongbong.pro.sharepermission.pojo.SharePermissionConditionFilters;
import com.xbongbong.pro.sharepermission.pojo.SharePermissionConditionPojo;
import com.xbongbong.pro.sharepermission.pojo.SharePermissionJointConditionPojo;
import com.xbongbong.pro.sharepermission.pojo.SharePermissionMidPojo;
import com.xbongbong.pro.sharepermission.pojo.dto.BaseSharePermissionDTO;
import com.xbongbong.pro.sharepermission.pojo.dto.ShareFilterConditionDTO;
import com.xbongbong.pro.sharepermission.pojo.dto.SharePermissionListDTO;
import com.xbongbong.pro.sharepermission.pojo.dto.SharePermissionSaveDTO;
import com.xbongbong.pro.sharepermission.pojo.dto.SharePermissionSupportDTO;
import com.xbongbong.pro.sharepermission.pojo.vo.SharePermissionListVO;
import com.xbongbong.pro.sharepermission.pojo.vo.SharePermissionSupportVO;
import com.xbongbong.pro.sharepermission.pojo.vo.SharePermissionVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.SharePermissionSetUserEntity;
import com.xbongbong.saas.domain.entity.ShareRuleEntity;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.base.ManagementBaseEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.help.SharePermissionHelper;
import com.xbongbong.saas.help.StageHelp;
import com.xbongbong.saas.service.ShareRuleService;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserDepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.SharePermissionSetUserModel;
import com.xbongbong.sys.model.ShareRuleModel;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.tomcat.util.buf.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author leex
 */
@Service("shareRuleService")
public class ShareRuleServiceImpl implements ShareRuleService {

    private static final Logger LOG = LoggerFactory.getLogger(ShareRuleServiceImpl.class);

    @Resource
    private SharePermissionHelper sharePermissionHelper;
    @Resource
    private ShareRuleModel shareRuleModel;
    @Resource
    private SharePermissionSetUserModel sharePermissionSetUserModel;
    @Resource
    private UserModel userModel;
    @Resource
    private FormHelp formHelp;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private LogThreadPoolBeanConfig logThreadPoolBeanConfig;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasAppModel paasAppModel;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private StageProcessModel stageProcessModel;
    @Resource
    private StageHelp stageHelp;
    @Resource
    private SharePermissionHelp sharePermissionHelp;

    @Override
    public SharePermissionListVO list(SharePermissionListDTO sharePermissionListDTO) throws Exception {
        String corpid = sharePermissionListDTO.getCorpid();

        SharePermissionListVO res = new SharePermissionListVO();
        //根据筛选条件获取列表数据
        Map<String, Object> filterMap = sharePermissionHelper.getFilterMap(corpid, sharePermissionListDTO.getAppId(),
                sharePermissionListDTO.getFormId(), sharePermissionListDTO.getNameLike(), sharePermissionListDTO.getRangeScreen());
        PageHelper pageHelper = PageHelperUtil.getPageHelper(filterMap, shareRuleModel,
                sharePermissionListDTO.getPage(), sharePermissionListDTO.getPageSize());
        List<ShareRuleEntity> entityList = (List<ShareRuleEntity>) PageHelperUtil.getEntityList(filterMap, pageHelper, shareRuleModel);
        List<SharePermissionVO> list = new ArrayList<>();
        if (entityList.isEmpty()) {
            return res;
        }

        //获取 formNameMap、userNameMap
        List<Long> formIds = new ArrayList<>();
        List<String> userIds = new ArrayList<>();
        for (ShareRuleEntity shareRuleEntity : entityList) {
            formIds.add(shareRuleEntity.getFormId());
            List<String> userIdList = JSONArray.parseArray(JSON.toJSONString(shareRuleEntity.getAuthorityUser()), String.class);
            userIds.addAll(userIdList);
        }
        Map<String, String> userNameMap = userModel.getUserNameMap(corpid, userIds, 1);
        Map<Long, String> formNameMap = formHelp.getNameMap(corpid, formIds);

        //拼接列表所需显示字段
        for (ShareRuleEntity entity : entityList) {
            String authorityNameStr = sharePermissionHelper.getAuthorityNameStr(entity.getAuthority(), entity.getAuthorityUser(), userNameMap);
            SharePermissionVO vo = new SharePermissionVO(entity.getId(), entity.getName(), entity.getFormId(),
                    formNameMap.getOrDefault(entity.getFormId(), ""), authorityNameStr, entity.getPermission());
            list.add(vo);
        }
        res.setList(list);
        res.setPageHelper(pageHelper);
        return res;
    }

    @Override
    public SharePermissionVO get(BaseSharePermissionDTO baseSharePermissionDTO) throws Exception {
        ShareRuleEntity shareRuleEntity = shareRuleModel.getByKey(baseSharePermissionDTO.getId(), baseSharePermissionDTO.getCorpid());
        if (Objects.isNull(shareRuleEntity) || Objects.equals(1, shareRuleEntity.getDel())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404);
        }
        PaasFormEntity formEntity = formHelp.getForm(baseSharePermissionDTO.getCorpid(), shareRuleEntity.getFormId());
        if (Objects.isNull(formEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018.getCode(), I18nStringConstant.FORM_NOT_EXIST);
        }

        JSONObject condition = getDisplayCondition(baseSharePermissionDTO, shareRuleEntity);

        return new SharePermissionVO(shareRuleEntity.getId(), shareRuleEntity.getName(), shareRuleEntity.getFormId(),
                formEntity.getName(), shareRuleEntity.getAuthority(), shareRuleEntity.getPermission(), condition,
                formEntity.getAppId(), formEntity.getMenuId(), shareRuleEntity.getSaasMark(), shareRuleEntity.getBusinessType());
    }

    /**
     * 获取回显的condition for 原字段在表单中被删除情况
     * @param baseSharePermissionDTO
     * @param shareRuleEntity
     * @return
     * @throws XbbException
     */
    private JSONObject getDisplayCondition(BaseSharePermissionDTO baseSharePermissionDTO, ShareRuleEntity shareRuleEntity) throws XbbException {
        PaasFormExplainEntity explainEntity = paasFormExplainModel.getByFormId(shareRuleEntity.getFormId(), baseSharePermissionDTO.getCorpid());
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explainEntity.getExplains());

        SharePermissionJointConditionPojo shareConditionPojo = JSONObject.parseObject(shareRuleEntity.getCondition().toJSONString(),
                SharePermissionJointConditionPojo.class);
        for (SharePermissionConditionFilters outFilter : shareConditionPojo.getFilters()) {
            for (SharePermissionConditionPojo innerFilter : outFilter.getFilter()) {
                if (!explainMap.containsKey(innerFilter.getAttr())) {
                    innerFilter.setName(innerFilter.getAttr());
                    continue;
                }
                FieldAttrEntity fieldAttrEntity = explainMap.get(innerFilter.getAttr());
                if (Objects.equals(fieldAttrEntity.getIsOpen(), 1)) {
                    continue;
                }
                innerFilter.setName(innerFilter.getAttr());
            }
        }
        return (JSONObject) JSONObject.toJSON(shareConditionPojo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO add(SharePermissionSaveDTO sharePermissionSaveDTO) throws Exception {
        String corpid = sharePermissionSaveDTO.getCorpid();

        validateValue(sharePermissionSaveDTO);
        validateCompanyAndFormRule(corpid, sharePermissionSaveDTO.getFormId(), true);
        validateRuleName(sharePermissionSaveDTO.getName(), corpid, sharePermissionSaveDTO.getId());

        Set<String> userIdList = new HashSet<>();
        ShareRuleEntity shareRuleEntity = getShareRuleEntityAndParam(userIdList, sharePermissionSaveDTO);
        validateUserRule(corpid, sharePermissionSaveDTO.getFormId(), new ArrayList<>(userIdList), shareRuleEntity.getId());
        try {
            shareRuleModel.insert(shareRuleEntity);
        } catch (Exception e) {
            LOG.error("shareRule数据库保存失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(ErrorMessageConstant.SAVE_ERROR));
        }

        List<SharePermissionSetUserEntity> insertList = userIdList.stream()
                .map(userId -> new SharePermissionSetUserEntity(null, corpid, shareRuleEntity.getAppId(),
                        shareRuleEntity.getId(), shareRuleEntity.getFormId(),
                        userId, DelEnum.NORMAL.getDel()))
                .collect(Collectors.toList());
        try {
            sharePermissionSetUserModel.insertBatch(insertList);
        } catch (Exception e) {
            LOG.error("sharePermissionSetUser数据库保存失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(ErrorMessageConstant.SAVE_ERROR));
        }

        Runnable runnable = () -> {
            try {
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_SHARE_RULE_PERMISSION), sharePermissionSaveDTO.getLoginUserName(), OperateTypeEnum.NEW.getName(), shareRuleEntity.getName());
                mongoLogHelp.buildLog(corpid, sharePermissionSaveDTO.getUserId(), sharePermissionSaveDTO.getLoginUserName(), OperateModuleTypeEnum.SHARE_RULE_PERMISSION, OperateTypeEnum.NEW,
                        shareRuleEntity.getId().toString(), shareRuleEntity.getName(), memo, sharePermissionSaveDTO.getHttpHeader());

            } catch (XbbException e) {
                LOG.error("com.xbongbong.service.impl.ShareRuleServiceImpl error", e);
            }
        };
        logThreadPoolBeanConfig.sysLogThreadPool().execute(runnable);

        return new BaseVO();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO save(SharePermissionSaveDTO sharePermissionSaveDTO) throws Exception {
        validateValue(sharePermissionSaveDTO);
        if (Objects.isNull(sharePermissionSaveDTO.getId())) {
            LOG.error("SharePermissionSaveDTO 缺少id主键");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(ErrorMessageConstant.SAVE_ERROR));
        }
        String corpid = sharePermissionSaveDTO.getCorpid();
        ShareRuleEntity oldShareRuleEntity = shareRuleModel.getByKey(sharePermissionSaveDTO.getId(),corpid);
        if (Objects.isNull(oldShareRuleEntity) || Objects.equals(oldShareRuleEntity.getDel(), DelEnum.DELETE.getDel())) {
            LOG.error("SharePermissionSaveDTO 数据库未找到数据 oldShareRuleEntity");
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(ErrorMessageConstant.SAVE_ERROR));
        }
        validateCompanyAndFormRule(corpid, sharePermissionSaveDTO.getFormId(), false);
        validateRuleName(sharePermissionSaveDTO.getName(), corpid, sharePermissionSaveDTO.getId());

        Set<String> userIdList = new HashSet<>();
        ShareRuleEntity shareRuleEntity = getShareRuleEntityAndParam(userIdList, sharePermissionSaveDTO);
        validateUserRule(corpid, sharePermissionSaveDTO.getFormId(), new ArrayList<>(userIdList), shareRuleEntity.getId());

        try {
            shareRuleModel.update(shareRuleEntity);
        } catch (Exception e) {
            LOG.error("shareRule数据库保存失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, I18nMessageUtil.getMessage(ErrorMessageConstant.SAVE_ERROR));
        }

        List<SharePermissionSetUserEntity> insertList = new ArrayList<>();
        List<SharePermissionSetUserEntity> updateList = new ArrayList<>();
        getChangedData(sharePermissionSaveDTO, corpid, shareRuleEntity.getAppId(), shareRuleEntity.getFormId(), userIdList, insertList, updateList);

        sharePermissionSetUserModel.updateBatch(corpid, updateList);
        sharePermissionSetUserModel.insertBatch(insertList);

        Runnable runnable = () -> {
            try {
                List<DetailLogPojo> detailArr = getDetailArr4SharePermission(oldShareRuleEntity, shareRuleEntity, corpid, sharePermissionSaveDTO.getBusinessType(), sharePermissionSaveDTO.getSaasMark(), sharePermissionSaveDTO.getFormId());
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_SHARE_RULE_PERMISSION), sharePermissionSaveDTO.getLoginUserName(), OperateTypeEnum.EDIT.getName(), shareRuleEntity.getName());
                mongoLogHelp.buildLog4DetailArr(detailArr, corpid, sharePermissionSaveDTO.getUserId(), sharePermissionSaveDTO.getLoginUserName(), OperateModuleTypeEnum.SHARE_RULE_PERMISSION, OperateTypeEnum.EDIT,
                        shareRuleEntity.getId().toString(), shareRuleEntity.getName(), memo, sharePermissionSaveDTO.getHttpHeader());

            } catch (XbbException e) {
                LOG.error("com.xbongbong.service.impl.ShareRuleServiceImpl error", e);
            }
        };
        logThreadPoolBeanConfig.sysLogThreadPool().execute(runnable);

        return new BaseVO();
    }

    /**
     * 权限获取详情数据
     * @param oldEntity
     * @param newEntity
     * @return
     */
    private List<DetailLogPojo> getDetailArr4SharePermission(ShareRuleEntity oldEntity, ShareRuleEntity newEntity, String corpid, Integer businessType, Integer saasMark, Long formId) throws XbbException {
        List<DetailLogPojo> res = new ArrayList<>();
        if (!Objects.equals(oldEntity.getName(), newEntity.getName())) {
            res.add(new DetailLogPojo(I18nMessageUtil.getMessage(I18nStringConstant.RULE_NAME), oldEntity.getName(), newEntity.getName()));
        }
        if (!CompareUtil.compareJson(oldEntity.getCondition(), newEntity.getCondition())) {
            SharePermissionJointConditionPojo oldCondition = oldEntity.getCondition().toJavaObject(SharePermissionJointConditionPojo.class);
            SharePermissionJointConditionPojo newCondition = newEntity.getCondition().toJavaObject(SharePermissionJointConditionPojo.class);

            PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(oldEntity.getCorpid(), oldEntity.getFormId(), oldEntity.getBusinessType());
            Map<String, FieldAttrEntity> oldAllFormExplainMap = ExplainUtil.getAllSubFormExplainMap(paasFormExplainEntity.getExplains());
            Map<String, FieldAttrEntity> newAllFormExplainMap = oldAllFormExplainMap;
            if (!Objects.equals(oldEntity.getFormId(), newEntity.getFormId())) {
                PaasFormExplainEntity explainEntity = proFormHelp.getExplainEntity(newEntity.getCorpid(), newEntity.getFormId(), newEntity.getBusinessType());
                newAllFormExplainMap = ExplainUtil.getAllSubFormExplainMap(explainEntity.getExplains());
            }
            //准备回显数据
            SharePermissionMidPojo sharePermissionMidPojo = prepareDisplayData(corpid, oldEntity, newEntity, oldCondition, newCondition, oldAllFormExplainMap, newAllFormExplainMap);
            String oldTranslatedCondition = getTranslatedCondition(oldCondition, oldAllFormExplainMap, oldEntity.getBusinessType(), oldEntity.getSaasMark(), oldEntity.getFormId(), sharePermissionMidPojo);
            String newTranslatedCondition = getTranslatedCondition(newCondition, newAllFormExplainMap, newEntity.getBusinessType(), newEntity.getSaasMark(), newEntity.getFormId(), sharePermissionMidPojo);
            res.add(new DetailLogPojo(I18nMessageUtil.getMessage(I18nStringConstant.SCREENING_CONDITION), oldTranslatedCondition, newTranslatedCondition));
        }
        if (!CompareUtil.compareArray(oldEntity.getAuthority(), newEntity.getAuthority())) {
            List<OptionalRangePojo> oldAuthorityList = JSONArray.parseArray(oldEntity.getAuthority().toJSONString(), OptionalRangePojo.class);
            List<OptionalRangePojo> newAuthorityList = JSONArray.parseArray(newEntity.getAuthority().toJSONString(), OptionalRangePojo.class);
            StringBuilder oldAuthorityStr = new StringBuilder();
            StringBuilder newAuthorityStr = new StringBuilder();

            oldAuthorityList.forEach(a -> oldAuthorityStr.append(a.getName()).append('、'));
            oldAuthorityStr.deleteCharAt(oldAuthorityStr.length() - 1);
            newAuthorityList.forEach(a -> newAuthorityStr.append(a.getName()).append('、'));
            newAuthorityStr.deleteCharAt(newAuthorityStr.length() - 1);

            res.add(new DetailLogPojo(I18nMessageUtil.getMessage(I18nStringConstant.AUTHORIZED_EMPLOYEE), oldAuthorityStr.toString(), newAuthorityStr.toString()));
        }
        if (!Objects.equals(oldEntity.getPermission(), newEntity.getPermission())) {
            res.add(new DetailLogPojo(I18nMessageUtil.getMessage(I18nStringConstant.DATA_PERMISSION),
                    Objects.equals(oldEntity.getPermission(), 0) ? I18nMessageUtil.getMessage(I18nStringConstant.READ_ONLY) : I18nMessageUtil.getMessage(I18nStringConstant.EDITABLE),
                    Objects.equals(newEntity.getPermission(), 0) ? I18nMessageUtil.getMessage(I18nStringConstant.READ_ONLY) : I18nMessageUtil.getMessage(I18nStringConstant.EDITABLE)));
        }
        res.add(new DetailLogPojo(I18nMessageUtil.getMessage(I18nStringConstant.UPDATE_TIME),
                DateUtil.getString(oldEntity.getUpdateTime() * 1000L, new SimpleDateFormat("yyyy-MM-dd HH:mm")),
                DateUtil.getString(DateTimeUtil.getLong(), new SimpleDateFormat("yyyy-MM-dd HH:mm"))));
        return res;
    }


    /**
     * 预准备需要查询的数据（人员、部门、关联数据、阶段推进器）
     * @param corpid
     * @param oldEntity
     * @param newEntity
     * @param oldCondition
     * @param newCondition
     * @param oldAllFormExplainMap
     * @param newAllFormExplainMap
     * @return
     */
    private SharePermissionMidPojo prepareDisplayData(String corpid, ShareRuleEntity oldEntity, ShareRuleEntity newEntity, SharePermissionJointConditionPojo oldCondition, SharePermissionJointConditionPojo newCondition,
                                                      Map<String, FieldAttrEntity> oldAllFormExplainMap, Map<String, FieldAttrEntity> newAllFormExplainMap) throws XbbException {
        Map<Long, Set<String>> formId2stageCodesMap = new HashMap<>();
        Map<Long, Integer> formId2BusinessTypeMap = new HashMap<>();
        Set<String> userIdList = new HashSet<>();
        Set<Long> deptIdList = new HashSet<>();
        Map<Integer, LinkInfoMidPojo> linkInfoMap = new HashMap<>();
        Map<Integer, LinkInfoMidPojo> linkBusinessMap = new HashMap<>();
        setParams(oldEntity.getFormId(), oldEntity.getSaasMark(), oldEntity.getBusinessType(), oldCondition, oldAllFormExplainMap,
                formId2stageCodesMap, formId2BusinessTypeMap, userIdList, deptIdList, linkInfoMap, linkBusinessMap);
        setParams(newEntity.getFormId(), newEntity.getSaasMark(), newEntity.getBusinessType(), newCondition, newAllFormExplainMap,
                formId2stageCodesMap, formId2BusinessTypeMap, userIdList, deptIdList, linkInfoMap, linkBusinessMap);
        //查询人员、部门
        Map<Long,String> linkValueMap = new HashMap<>();
        Map<String, String> userNameMap = userModel.getByUserIdIn(corpid, userIdList).stream().collect(Collectors.toMap(UserEntity::getUserId, UserEntity::getName));
        Map<Long, String> deptNameMap = departmentModel.getByDepIdIn(corpid, deptIdList).stream().collect(Collectors.toMap(DepartmentEntity::getId, DepartmentEntity::getName));
        //查询关联数据
        for (Map.Entry<Integer, LinkInfoMidPojo> entry : linkInfoMap.entrySet()) {
            Integer businessType = entry.getKey();
            Set<Long> dataIds = entry.getValue().getDataIds();
            String linkKey = entry.getValue().getLinkKey();
            int saasMark = Objects.equals(businessType, XbbRefTypeEnum.PAAS.getCode()) ? SaasMarkEnum.PAAS.getCode() : SaasMarkEnum.SAAS.getCode();
            Map<Long, PaasFormDataEntity> entityMap = userTeamHelp.getEntityMap(businessType, new ArrayList<>(dataIds), corpid, new HashMap<>(), saasMark);
            entityMap.forEach((dataId, paasFormDataEntity) -> {
                String linkValue;
                if (Objects.equals(FieldTypeEnum.SERIALNO.getAlias(), linkKey)) {
                    linkValue = paasFormDataEntity.getSerialNo();
                } else {
                    Object linkValueObject = paasFormDataEntity.getData().get(linkKey);
                    linkValue = Objects.nonNull(linkValueObject) ? linkValueObject.toString() : "linkKey:" + "Unknonw value";
                }
                linkValueMap.put(dataId, linkValue);
            });
        }
        //查询关联业务
        for (Map.Entry<Integer, LinkInfoMidPojo> entry : linkBusinessMap.entrySet()) {
            Integer businessType = entry.getKey();
            Set<Long> dataIds = entry.getValue().getDataIds();
            String linkKey = ManagementBaseEnum.NAME.getAttr();
            int saasMark = Objects.equals(businessType, XbbRefTypeEnum.PAAS.getCode()) ? SaasMarkEnum.PAAS.getCode() : SaasMarkEnum.SAAS.getCode();
            Map<Long, PaasFormDataEntity> entityMap = userTeamHelp.getEntityMap(businessType, new ArrayList<>(dataIds), corpid, new HashMap<>(), saasMark);
            entityMap.forEach((dataId, paasFormDataEntity) -> {
                String name = Objects.nonNull(paasFormDataEntity.getData().get(linkKey)) ? paasFormDataEntity.getData().get(linkKey).toString() : "linkKey:" + "Unknonw value";
                String serialNo = paasFormDataEntity.getSerialNo();
                linkValueMap.put(dataId, serialNo + name);
            });
        }
        //查询本表单的阶段推进器节点和版本信息
        List<PaasStageEntity> stageEntitys = new ArrayList<>();
        Map<Long, String> stageProcessVerMap = new HashMap<>();
        Map<String, PaasStageEntity> stageEntityMap = new HashMap<>();
        for (Map.Entry<Long, Set<String>> entry : formId2stageCodesMap.entrySet()) {
            Long formId = entry.getKey();
            Set<String> stageCodes = entry.getValue();
            Integer businessType = formId2BusinessTypeMap.get(formId);
            int saasMark;
            if (Objects.equals(businessType, XbbRefTypeEnum.PAAS.getCode())) {
                saasMark = SaasMarkEnum.PAAS.getCode();
            } else {
                saasMark = SaasMarkEnum.SAAS.getCode();
            }
            List<PaasStageEntity> stageEntitysByCodes = stageHelp.getStageEntitysByCodes(corpid, saasMark, businessType, formId, new ArrayList<>(stageCodes));
            stageEntitys.addAll(stageEntitysByCodes);
        }
        if (CollectionUtils.isNotEmpty(stageEntitys)) {
            Map<String, Long> code2StageProcessIdMap = new HashMap<>();
            for (PaasStageEntity entity : stageEntitys) {
                stageEntityMap.put(entity.getCode(), entity);
                code2StageProcessIdMap.put(entity.getCode(), entity.getStageProcessId());
            }
            Map<String, Object> params = new HashMap<>();
            params.put("columns", "id,version_name");
            params.put("corpid", corpid);
            params.put("idIn", code2StageProcessIdMap.values());
            params.put("del", DelEnum.NORMAL.getDel());
            List<StageProcessEntity> stageProcessEntityList = stageProcessModel.findEntitys(params);
            stageProcessVerMap = stageProcessEntityList.stream()
                    .collect(Collectors.toMap(StageProcessEntity::getId, StageProcessEntity::getVersionName));
        }
        return new SharePermissionMidPojo(corpid, userNameMap, deptNameMap, stageEntityMap, stageProcessVerMap, linkValueMap);
    }

    /**
     * 设置参数并获取 查数据库用（人员、部门、关联数据、阶段推进器）
     * @param formId
     * @param saasMark
     * @param businessType
     * @param condition
     * @param oldAllFormExplainMap
     * @param formId2stageCodesMap
     * @param formId2BusinessTypeMap
     * @param userIdList
     * @param deptIdList
     * @param linkInfoMap
     * @param linkBusinessMap
     */
    private void setParams(Long formId, Integer saasMark, Integer businessType, SharePermissionJointConditionPojo condition, Map<String, FieldAttrEntity> oldAllFormExplainMap, Map<Long, Set<String>> formId2stageCodesMap,
                           Map<Long, Integer> formId2BusinessTypeMap, Set<String> userIdList, Set<Long> deptIdList, Map<Integer, LinkInfoMidPojo> linkInfoMap, Map<Integer, LinkInfoMidPojo> linkBusinessMap) {
        for (SharePermissionConditionFilters filters : condition.getFilters()) {
            for (SharePermissionConditionPojo filter : filters.getFilter()) {
                List<Object> valueList = filter.getValue();
                if (CollectionUtils.isEmpty(valueList)) {
                    continue;
                }
                FieldAttrEntity fieldAttrEntity = oldAllFormExplainMap.get(filter.getAttr());
                if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.STAGE_THRUSTER.getType())) {
                    valueList.forEach(value -> {
                        if (!formId2stageCodesMap.containsKey(formId)) {
                            formId2stageCodesMap.put(formId, new HashSet<>());
                        }
                        if (!formId2BusinessTypeMap.containsKey(formId)) {
                            if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
                                formId2BusinessTypeMap.put(formId, businessType);
                            } else {
                                formId2BusinessTypeMap.put(formId, XbbRefTypeEnum.PAAS.getCode());
                            }
                        }
                        formId2stageCodesMap.get(formId).add(value.toString());
                    });
                } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.USER.getType())
                        || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.USER_GROUP.getType())
                        || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.CREATORID.getType())
                        || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.OWNERID.getType())
                        || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.COUSERID.getType())) {
                    valueList.forEach(value -> userIdList.add(value.toString()));
                } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.DEPT.getType())
                        || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.DEPT_GROUP.getType())
                        || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.DEPARTMENTID.getType())) {
                    valueList.forEach(value -> deptIdList.add(Long.parseLong(value.toString())));
                } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.LINK_DATA.getType())
                        || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.LINK_DATA_MULTI.getType())) {
                    valueList.forEach(value -> {
                        LinkInfoPojo linkInfo = fieldAttrEntity.getLinkInfo();
                        Integer linkBusinessType = linkInfo.getLinkBusinessType();
                        Integer linkSaasMark = linkInfo.getLinkSaasMark();
                        if (Objects.equals(linkSaasMark, SaasMarkEnum.PAAS.getCode())) {
                            linkBusinessType = XbbRefTypeEnum.PAAS.getCode();
                        }
                        long dataId = Long.parseLong(value.toString());
                        if (!linkInfoMap.containsKey(linkBusinessType)) {
                            linkInfoMap.put(linkBusinessType, new LinkInfoMidPojo());
                            linkInfoMap.get(linkBusinessType).setLinkKey(linkInfo.getLinkKey());
                        }
                        linkInfoMap.get(linkBusinessType).getDataIds().add(dataId);
                    });
                } else if (Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.LINK_BUSINESS_SINGLE.getType())
                        || Objects.equals(fieldAttrEntity.getFieldType(), FieldTypeEnum.LINK_BUSINESS_MULTI.getType())) {
                    valueList.forEach(value -> {
                        Integer linkBusinessType = Objects.equals(0, fieldAttrEntity.getLinkedType()) ? XbbRefTypeEnum.PAAS.getCode() : fieldAttrEntity.getLinkedType();
                        long dataId = Long.parseLong(value.toString());
                        if (!linkBusinessMap.containsKey(linkBusinessType)) {
                            linkBusinessMap.put(linkBusinessType, new LinkInfoMidPojo());
                            linkBusinessMap.get(linkBusinessType).setLinkKey(ManagementBaseEnum.NAME.getAttr());
                        }
                        linkBusinessMap.get(linkBusinessType).getDataIds().add(dataId);
                    });
                }
            }
        }
    }

    /**
     * 根据字段类型，将筛选条件转换成文本
     *
     * @param conditionPojo
     * @param allFormExplainMap
     * @param sharePermissionMidPojo
     * @return
     */
    private String getTranslatedCondition(SharePermissionJointConditionPojo conditionPojo, Map<String, FieldAttrEntity> allFormExplainMap,
                                          Integer businessType, Integer saasMark, Long formId, SharePermissionMidPojo sharePermissionMidPojo) throws XbbException {
        sharePermissionMidPojo.setAllFormExplainMap(allFormExplainMap);
        sharePermissionMidPojo.setBusinessType(businessType);
        sharePermissionMidPojo.setSaasMark(saasMark);
        sharePermissionMidPojo.setFormId(formId);

        StringBuilder sb = new StringBuilder();
        List<SharePermissionConditionFilters> filters = conditionPojo.getFilters();
        for (int i = 0; i < filters.size(); i++) {
            SharePermissionConditionFilters orFilter = filters.get(i);
            sb.append("（");
            List<SharePermissionConditionPojo> filter = orFilter.getFilter();
            for (int j = 0; j < filter.size(); j++) {
                SharePermissionConditionPojo andFilter = filter.get(j);
                sharePermissionMidPojo.setValue(andFilter.getValue());
                sharePermissionMidPojo.setAttr(andFilter.getAttr());
                sharePermissionMidPojo.setSubAttr(andFilter.getSubAttr());
                List<String> realValueList = getValuesName(sharePermissionMidPojo);
                ConditionEnum conditionEnum = ConditionEnum.getConditionEnum(andFilter.getSymbol());
                String valuesName = "";
                switch (conditionEnum) {
                    case EQUAL:
                    case NOEQUAL:
                    case INCLUDE:
                    case ALLINCLUDE:
                    case LIKE:
                    case NOLIKE:
                    case IN:
                    case NOIN:
                    case GREATEREQUAL:
                    case GREATERTHAN:
                    case LESSEQUAL:
                    case LESSTHAN:
                    case EMPTY:
                    case NOEMPTY:
                    case DYNAMIC:
                        valuesName = String.join(StringConstant.COMMA, realValueList);
                        break;
                    case RANGE:
                    case NORANGE:
                        valuesName = String.join(StringConstant.WAVY_LINE, realValueList);
                        break;
                    default:
                        break;
                }
                sb.append(andFilter.getName())
                        .append(ConditionEnum.getMemoBySymbo(andFilter.getSymbol()))
                        .append(valuesName);
                if (j != filter.size() - 1) {
                    sb.append(" ");
                    sb.append(orFilter.getOperator());
                    sb.append(" ");
                }
            }
            sb.append("）");
            if (i != filters.size() - 1) {
                sb.append(conditionPojo.getOperator());
            }
        }
        return sb.toString();
    }

    /**
     * 获取筛选条件实际value值
     *
     * @param sharePermissionMidPojo
     * @return
     */
    private List<String> getValuesName(SharePermissionMidPojo sharePermissionMidPojo) throws XbbException {
        List<Object> values = sharePermissionMidPojo.getValue();
        Map<String, FieldAttrEntity> allFormExplainMap = sharePermissionMidPojo.getAllFormExplainMap();
        String attr = sharePermissionMidPojo.getAttr();
        String subAttr = sharePermissionMidPojo.getSubAttr();

        if (CollectionUtils.isEmpty(values) || Objects.isNull(allFormExplainMap)
                || Objects.isNull(attr) || !allFormExplainMap.containsKey(attr)) {
            return new ArrayList<>();
        }
        FieldAttrEntity fieldAttrEntity = allFormExplainMap.get(attr);
        if(Objects.isNull(fieldAttrEntity)){
            return new ArrayList<>();
        }
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldAttrEntity.getFieldType());
        //子表单直接拿子字段进去转换
        if(!Objects.equals(fieldTypeEnum, FieldTypeEnum.SUB_FORM)){
            sharePermissionMidPojo.setFieldTypeEnum(fieldTypeEnum);
            sharePermissionMidPojo.setFieldAttrEntity(fieldAttrEntity);
            return transferFieldValue(sharePermissionMidPojo);
        }else{
            FieldAttrEntity subField = fieldAttrEntity.getSubForm().getItems().stream().filter(v -> Objects.equals(v.getAttr(), subAttr)).findFirst().get();
            FieldTypeEnum subFieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(subField.getFieldType());
            sharePermissionMidPojo.setFieldTypeEnum(subFieldTypeEnum);
            sharePermissionMidPojo.setFieldAttrEntity(subField);
            return transferFieldValue(sharePermissionMidPojo);
        }
    }

    /**
     * 把设置的字段值转换成文本用于日志记录
     *
     * @param sharePermissionMidPojo
     * @return 返回转换后的值
     * @throws XbbException
     */
    private List<String> transferFieldValue(SharePermissionMidPojo sharePermissionMidPojo) {
        List<Object> value = sharePermissionMidPojo.getValue();
        Map<String, String> allUserMap = sharePermissionMidPojo.getAllUserMap();
        Map<Long, String> allDeptMap = sharePermissionMidPojo.getAllDeptMap();
        FieldTypeEnum fieldTypeEnum = sharePermissionMidPojo.getFieldTypeEnum();
        FieldAttrEntity fieldAttrEntity = sharePermissionMidPojo.getFieldAttrEntity();
        Map<String, PaasStageEntity> stageEntityMap = sharePermissionMidPojo.getStageEntityMap();
        Map<Long, String> stageProcessVerMap = sharePermissionMidPojo.getStageProcessVerMap();
        Map<Long, String> linkValueMap = sharePermissionMidPojo.getLinkValueMap();

        List<String> valueList = new ArrayList<>();
        switch(fieldTypeEnum){
            case DATETIME:
            case ADDTIME:
            case UPDATETIME:
                //日期，创建时间，更新时间
                for (Object o : value) {
                    if (o instanceof String) {
                        String dateEnumMemo = DateEnum.getDateEnumMemo(o.toString());
                        valueList.add(dateEnumMemo);
                    } else {
                        Long date = Long.parseLong(o.toString());
                        String realDate = DateUtil.getString(date * 1000, new SimpleDateFormat("yyyy-MM-dd HH:mm"));
                        valueList.add(realDate);
                    }
                }
                break;
            case RADIO_GROUP:
            case COMBO:
            case COMBO_CHECK:
            case CHECKBOX_GROUP:
                //按钮单选，下拉框，下拉框多选，复选框组
                List<ItemPoJo> items = fieldAttrEntity.getItems();
                Map<String, String> itemMap = items.stream().collect(Collectors.toMap(v -> v.getValue().toString(), ItemPoJo::getText));
                value.forEach(v -> {
                    //单选按钮的包含不在itemMap中
                    valueList.add(itemMap.getOrDefault(v.toString(), v.toString()));
                });
                break;
            case LINK_DATA:
            case LINK_DATA_MULTI:
            case LINK_BUSINESS_SINGLE:
            case LINK_BUSINESS_MULTI:
                //关联数据，关联数据多选
                if (MapUtils.isNotEmpty(linkValueMap)) {
                    value.forEach(v -> {
                        valueList.add(linkValueMap.getOrDefault(Long.parseLong(v.toString()), "Unknown value"));
                    });
                }
                break;
            case USER:
            case USER_GROUP:
            case CREATORID:
            case OWNERID:
            case COUSERID:
                //成员单选，成员多选，创建者，负责人，协同人
                List<String> userIdList = value.stream().map(Object::toString).collect(Collectors.toList());
                userIdList.forEach(v -> {
                    valueList.add(allUserMap.get(v));
                });
                break;
            case DEPT:
            case DEPT_GROUP:
            case DEPARTMENTID:
                //部门单选，部门多选，所属部门
                List<Long> deptIdList = value.stream().map(v -> Long.parseLong(v.toString())).collect(Collectors.toList());
                deptIdList.forEach(v -> {
                    valueList.add(allDeptMap.get(v));
                });
                break;
            case TEXT:
            case TEXTAREA:
            case NUM:
            case SERIALNO:
            case STAGE_RATIO:
                value.forEach( v -> {
                    valueList.add(v.toString());
                });
                break;
            case ADDRESS:
                //地址
                String address = value.stream().map(Object::toString).collect(Collectors.joining(StringConstant.COMMA));
                valueList.add(address);
                break;
            case STAGE_THRUSTER:
                //阶段推进器
                for (Object o : value) {
                    PaasStageEntity paasStageEntity = stageEntityMap.get(o.toString());
                    String verName = stageProcessVerMap.get(paasStageEntity.getStageProcessId());
                    verName = StringUtil.isEmpty(verName) ? "Unknown version" : verName;
                    String realValue = paasStageEntity.getName() + "(" + verName + ")";
                    valueList.add(realValue);
                }
                break;
            default:
                break;
        }
        return valueList;
    }

    /**
     * 获取需要插入的数据 and 需要删除的 IdList
     * @param sharePermissionSaveDTO
     * @param corpid
     * @param nowAppId
     * @param nowFormId
     * @param userIdList
     * @param insertList
     * @param updateList
     */
    private void getChangedData(SharePermissionSaveDTO sharePermissionSaveDTO, String corpid, Long nowAppId, Long nowFormId, Set<String> userIdList,
                                List<SharePermissionSetUserEntity> insertList, List<SharePermissionSetUserEntity> updateList) {

        //数据库中旧的数据
        List<SharePermissionSetUserEntity> oldSetUsers = sharePermissionSetUserModel.getByShareRuleId(sharePermissionSaveDTO.getId(), corpid);
        Map<String, SharePermissionSetUserEntity> oldSetUserMap = oldSetUsers.stream()
                .collect(Collectors.toMap(SharePermissionSetUserEntity::getUserId, entity -> entity, (a, b) -> b));
        boolean isChangeForm = false;
        if (CollectionUtils.isNotEmpty(oldSetUsers)) {
            SharePermissionSetUserEntity firstSetUserEntity = oldSetUsers.get(0);
            Long oldFormId = firstSetUserEntity.getFormId();
            Long oldAppId = firstSetUserEntity.getAppId();
            if (!Objects.equals(oldAppId, nowAppId) || !Objects.equals(oldFormId, nowFormId)) {
                isChangeForm = true;
            }
        }
        //新增和保留的
        List<SharePermissionSetUserEntity> keepList = new ArrayList<>();
        for (String userId : userIdList) {
            if (oldSetUserMap.containsKey(userId)) {
                SharePermissionSetUserEntity sharePermissionSetUserEntity = oldSetUserMap.get(userId);
                keepList.add(sharePermissionSetUserEntity);
                if (isChangeForm) {
                    sharePermissionSetUserEntity.setAppId(nowAppId);
                    sharePermissionSetUserEntity.setFormId(nowFormId);
                    updateList.add(sharePermissionSetUserEntity);
                }
            } else {
                SharePermissionSetUserEntity sharePermissionSetUserEntity = new SharePermissionSetUserEntity(null, corpid, sharePermissionSaveDTO.getAppId(),
                        sharePermissionSaveDTO.getId(), sharePermissionSaveDTO.getFormId(), userId, 0);
                insertList.add(sharePermissionSetUserEntity);
            }
        }

        //删除的
        List<SharePermissionSetUserEntity> deleteList = new ArrayList<>(oldSetUsers);
        deleteList.removeAll(keepList);
        if (CollectionUtils.isNotEmpty(deleteList)) {
            for (SharePermissionSetUserEntity sharePermissionSetUserEntity : deleteList) {
                SharePermissionSetUserEntity delUser = new SharePermissionSetUserEntity();
                delUser.setDel(DelEnum.DELETE.getDel());
                delUser.setId(sharePermissionSetUserEntity.getId());
                updateList.add(delUser);
            }
        }
    }

    /**
     * 校验值是否为空
     * @param sharePermissionSaveDTO
     * @throws XbbException
     */
    private void validateValue(SharePermissionSaveDTO sharePermissionSaveDTO) throws XbbException {
        SharePermissionJointConditionPojo condition = sharePermissionSaveDTO.getCondition();
        for (SharePermissionConditionFilters filter : condition.getFilters()) {
            for (SharePermissionConditionPojo sharePermissionConditionPojo : filter.getFilter()) {
                List<Object> value = sharePermissionConditionPojo.getValue();
                String symbol = sharePermissionConditionPojo.getSymbol();
                ConditionEnum conditionEnum = ConditionEnum.getConditionEnum(symbol);
                switch (conditionEnum) {
                    case EQUAL:
                    case NOEQUAL:
                    case INCLUDE:
                    case ALLINCLUDE:
                    case LIKE:
                    case NOLIKE:
                    case IN:
                    case NOIN:
                    case GREATEREQUAL:
                    case GREATERTHAN:
                    case LESSEQUAL:
                    case LESSTHAN:
                    case RANGE:
                    case NORANGE:
                    case NORMAL:
                    case CUSTOM:
                    case DYNAMIC:
                        if (CollectionUtils.isEmpty(value)) {
                            throw new XbbException(SharePermissionErrorCodeEnum.API_ERROR_345007);
                        }
                        break;
                    case EMPTY:
                    case NOEMPTY:
                        break;
                    default:
                }
            }
        }
    }

    /**
     * 校验名称重复
     * @param name
     * @param corpid
     * @param ruleId
     * @throws XbbException
     */
    private void validateRuleName(String name, String corpid, Long ruleId) throws XbbException {
        Map<String,Object> params = new HashMap<>();
        params.put("corpid", corpid);
        params.put("name", name);
        params.put("negId", ruleId);
        params.put("del", DelEnum.NORMAL.getDel());
        Integer count = shareRuleModel.getEntitysCount(params);

        if (count >= 1) {
            throw new XbbException(SharePermissionErrorCodeEnum.API_ERROR_345004, SharePermissionErrorCodeEnum.API_ERROR_345004.getMsg());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO delete(BaseSharePermissionDTO baseSharePermissionDTO) throws Exception {
        BaseVO res = new BaseVO();
        String corpid = baseSharePermissionDTO.getCorpid();
        ShareRuleEntity shareRuleEntity = shareRuleModel.getByKey(baseSharePermissionDTO.getId(), corpid);
        if (Objects.isNull(shareRuleEntity) || Objects.equals(1, shareRuleEntity.getDel())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018);
        }
        shareRuleModel.deleteByKey(shareRuleEntity.getId(), shareRuleEntity.getCorpid());
        sharePermissionSetUserModel.deleteByShareRuleId(shareRuleEntity.getId(), shareRuleEntity.getCorpid(), shareRuleEntity.getFormId());

        Runnable runnable = () -> {
            try {
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_SHARE_RULE_PERMISSION), baseSharePermissionDTO.getLoginUserName(), OperateTypeEnum.DELETE.getName(), shareRuleEntity.getName());
                mongoLogHelp.buildLog(corpid, baseSharePermissionDTO.getUserId(), baseSharePermissionDTO.getLoginUserName(), OperateModuleTypeEnum.SHARE_RULE_PERMISSION, OperateTypeEnum.DELETE,
                        shareRuleEntity.getId().toString(), shareRuleEntity.getName(), memo, baseSharePermissionDTO.getHttpHeader());
            } catch (XbbException e) {
                LOG.error("com.xbongbong.service.impl.ShareRuleServiceImpl error", e);
            }
        };
        logThreadPoolBeanConfig.sysLogThreadPool().execute(runnable);

        return res;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseVO recalculate(BaseDTO baseDTO) throws XbbException {
        BaseVO res = new BaseVO();
        String corpid = baseDTO.getCorpid();

        Map<Long, ShareRuleEntity> shareRuleMap = new HashMap<>();
        Map<Long, Integer> formNumMap = new HashMap<>();

        Map<Long, Set<String>> newRuleId2UsersMap = new HashMap<>();
        Map<Long, List<SharePermissionSetUserEntity>> oldRuleId2UsersMap = new HashMap<>();

        setNewUserParams(corpid, shareRuleMap, formNumMap,  newRuleId2UsersMap);
        setOldUserParams(corpid, oldRuleId2UsersMap);

        List<Long> allNeedDeleteIds = new ArrayList<>();
        List<SharePermissionSetUserEntity> allNeedAddUsers = new ArrayList<>();

        getAddAndDelData(corpid, shareRuleMap, formNumMap, newRuleId2UsersMap, oldRuleId2UsersMap, allNeedDeleteIds, allNeedAddUsers);

        if (!allNeedDeleteIds.isEmpty()) {
            sharePermissionSetUserModel.deleteBatch(corpid, allNeedDeleteIds);
        }
        if (!allNeedAddUsers.isEmpty()) {
            sharePermissionSetUserModel.insertBatch(allNeedAddUsers);
        }

        return res;
    }

    @Override
    public ApplicationListVO appList(ApplicationListDTO applicationListDTO) {

        ApplicationListVO res = new ApplicationListVO();
        res.setAppList(sharePermissionHelper.getEnableAppList(applicationListDTO.getCorpid()));
        return res;
    }



    @Override
    public SharePermissionSupportVO isSupport(SharePermissionSupportDTO supportDTO) {
        SharePermissionSupportVO res = new SharePermissionSupportVO();
        Long appId = supportDTO.getAppId();
        Integer isSupport = 0;
        boolean permission = supportDTO.getLoginUser().getPermSet().contains(ProPermissionAliasEnum.SHARE_PERMISSION.getAlias());
        boolean isWhiteCompany = sharePermissionHelp.checkSharePermissionWhite(supportDTO.getCorpid());
        if (permission && isWhiteCompany) {
            if (Objects.equals(supportDTO.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                PaasAppEntity appEntity = paasAppModel.getByKey(appId, supportDTO.getCorpid());
                if (ShareSupportFormEnum.getSupportListByAppAlias(appEntity.getAlias()).contains(supportDTO.getBusinessType())) {
                    isSupport = 1;
                }
            } else {
                isSupport = 1;
            }
        }
        res.setIsSupport(isSupport);
        return res;
    }


    /**
     * 抄 PaasFormExplainServiceImpl#ruleFilterConditionList （工作流的）
     * @param shareFilterConditionDTO
     * @return
     */
    @Override
    public ExplainFilterConditionVO conditionList(ShareFilterConditionDTO shareFilterConditionDTO) {
        ExplainFilterConditionVO res = new ExplainFilterConditionVO();
        String corpid = shareFilterConditionDTO.getCorpid();
        try {
            JSONArray list = ShareConditionBusinessFieldEnum.getAttrsByCode(shareFilterConditionDTO.getBusinessType());
            PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, shareFilterConditionDTO.getFormId(), shareFilterConditionDTO.getBusinessType());
            List<FieldAndLogicPojo> conditionFieldList = new ArrayList<>();
            if (paasFormExplainEntity != null) {
                List<FieldAttrEntity> fieldList = JSON.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                for (FieldAttrEntity fieldAttrEntity : fieldList) {
                    if (Objects.equals(shareFilterConditionDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
                        //仅客户这样的情况
                        if (Objects.equals(fieldAttrEntity.getAttr(), CustomerManagementEnum.CREATOR_ID.getAttr())) {
                            fieldAttrEntity.setAttrName(CustomerManagementEnum.CREATOR.getAttrName());
                        }
                    }
                    // 添加条件
                    addConditionField(conditionFieldList, fieldAttrEntity, list);
                }

                for (Object o : list) {
                    String attr = (String) o;
                    boolean has = false;
                    String name = "XXXXXXXXXXX:"+shareFilterConditionDTO.getBusinessType() + attr;
                    for (FieldAndLogicPojo fieldAndLogicPojo : conditionFieldList) {
                        if (Objects.equals(attr, fieldAndLogicPojo.getAttr())) {
                            has = true;
                            break;
                        }
                    }
                    if (!has) {
                        LOG.error(name);
                    }
                }
            }
            res.setExplainList(conditionFieldList);

        } catch (XbbException e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 添加条件
     * @param conditionFieldList
     * @param fieldAttrEntity
     * @param list
     */
    private void addConditionField(List<FieldAndLogicPojo> conditionFieldList, FieldAttrEntity fieldAttrEntity, JSONArray list) {
        if (!ExplainUtil.isSubForm(fieldAttrEntity.getFieldType())) {
            addFieldAndLogic(conditionFieldList, fieldAttrEntity, null, list, false);
        } else {
            if (Objects.isNull(fieldAttrEntity.getSubForm()) || fieldAttrEntity.getSubForm().getItems().isEmpty()) {
                return;
            }
            fieldAttrEntity.getSubForm().getItems()
                    .forEach(item -> addFieldAndLogic(conditionFieldList, fieldAttrEntity, item, list, true));
        }
    }

    /**
     * 添加字段的可用逻辑符
     * @param conditionFieldList
     * @param parentFieldEntity
     * @param sonfieldEntity 如果非子表单，则为null
     * @param list
     * @param isSubForm
     */
    private void addFieldAndLogic(List<FieldAndLogicPojo> conditionFieldList, FieldAttrEntity parentFieldEntity, FieldAttrEntity sonfieldEntity, JSONArray list, boolean isSubForm) {
        FieldAttrEntity specificFieldAttrEntity = isSubForm ? sonfieldEntity : parentFieldEntity;
        ShareRuleFilterConditionEnum ruleFilterConditionEnum = ShareRuleFilterConditionEnum.getByCode(specificFieldAttrEntity.getFieldType());
        boolean isSuport = isSupport4FieldCondition(parentFieldEntity, list, ruleFilterConditionEnum);
        if (!isSuport) {
            return;
        }
        String attr = isSubForm ? parentFieldEntity.getAttr() + "." + sonfieldEntity.getAttr() : parentFieldEntity.getAttr();
        String attrName = isSubForm ? parentFieldEntity.getAttrName() + "." + sonfieldEntity.getAttrName() : parentFieldEntity.getAttrName();
        FieldAndLogicPojo fieldAndLogicPojo = new FieldAndLogicPojo(attr, specificFieldAttrEntity.getFieldType(), attrName,
                specificFieldAttrEntity.getVisible(), specificFieldAttrEntity.getEditable(), specificFieldAttrEntity.getSaasParticularAttributePoJo());
        List<LogicPojo> logicList = proFormHelp.getLogicList(ruleFilterConditionEnum.getConditionFields(), 0);
        // 设置值类型
        // 按照字段类型设置属性
        proFormHelp.setFieldAttr(specificFieldAttrEntity, fieldAndLogicPojo);
        fieldAndLogicPojo.setLogicList(logicList);
        conditionFieldList.add(fieldAndLogicPojo);
    }


    /**
     * 是否支持该字段（判断字段开启、可见、系统字段时需要在list中，非系统字段时showType有要求）
     * @param fieldAttrEntity
     * @param list
     * @param ruleFilterConditionEnum
     * @return
     */
    private boolean isSupport4FieldCondition(FieldAttrEntity fieldAttrEntity, JSONArray list, ShareRuleFilterConditionEnum ruleFilterConditionEnum) {
        boolean isOpen = Objects.equals(EnableEnum.OPEN.getCode(), fieldAttrEntity.getIsOpen()) && Objects.equals(EnableEnum.OPEN.getCode(), fieldAttrEntity.getVisible());
        boolean sysFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ZERO)
                && ((Objects.nonNull(list) && list.contains(fieldAttrEntity.getAttr()))
                    || ShareRuleFilterConditionEnum.extraSystemSupportField().contains(fieldAttrEntity.getFieldType()));
        boolean isSupportFieldType = Objects.nonNull(ruleFilterConditionEnum);
        // 自定义字段
        boolean cusFlag = Objects.equals(fieldAttrEntity.getIsRedundant(), BasicConstant.ONE)
                && (Objects.isNull(fieldAttrEntity.getShowType()) || Objects.equals(ShowTypeEnum.ALL.getCode(), fieldAttrEntity.getShowType()));
        if (sysFlag && !isSupportFieldType) {
            LOG.error("需要添加的fieldType : " + fieldAttrEntity.getFieldType() + "(" + fieldAttrEntity.getAttr() + fieldAttrEntity.getAttrName() + ")");
        }
        return isOpen && isSupportFieldType && (sysFlag || cusFlag);
    }

    /**
     * 获取 需要添加和删除的数据
     * @param corpid
     * @param shareRuleMap
     * @param formNumMap
     * @param newRuleId2UsersMap
     * @param oldRuleId2UsersMap
     * @param allNeedDeleteIds
     * @param allNeedAddUsers
     * @throws XbbException
     */
    private void getAddAndDelData(String corpid, Map<Long, ShareRuleEntity> shareRuleMap, Map<Long, Integer> formNumMap,
                                  Map<Long, Set<String>> newRuleId2UsersMap, Map<Long, List<SharePermissionSetUserEntity>> oldRuleId2UsersMap,
                                  List<Long> allNeedDeleteIds, List<SharePermissionSetUserEntity> allNeedAddUsers) throws XbbException {
        if (Objects.isNull(newRuleId2UsersMap) || newRuleId2UsersMap.isEmpty()) {
            return;
        }
        Set<Long> allRuleIdSet = new HashSet<>(oldRuleId2UsersMap.keySet());
        allRuleIdSet.addAll(newRuleId2UsersMap.keySet());
        Map<Long, Map<String,Integer>> formUserNumMap = new HashMap<>();
        //循环处理 每一条规则
        for (Long ruleId : allRuleIdSet) {
            Set<String> userIdNew = newRuleId2UsersMap.getOrDefault(ruleId, new HashSet<>());
            Set<String> userIdsOld = oldRuleId2UsersMap.getOrDefault(ruleId, new ArrayList<>()).stream()
                    .map(SharePermissionSetUserEntity::getUserId)
                    .collect(Collectors.toSet());
            if (Objects.equals(userIdNew.size(), userIdsOld.size())) {
                //前后人员相同 则无需处理
                continue;
            }
            // 计算增减的人员
            List<String> needAddUserIds = new ArrayList<>(userIdNew);
            List<String> needDeleteUserIds = new ArrayList<>(userIdsOld);
            List<String> intersectionData = new ArrayList<>(needAddUserIds);
            intersectionData.retainAll(needDeleteUserIds);
            needAddUserIds.removeAll(intersectionData);
            needDeleteUserIds.removeAll(intersectionData);

            if (!needAddUserIds.isEmpty()) {
                //通过ruleId --- 去拿到 formId
                ShareRuleEntity shareRuleEntity = shareRuleMap.get(ruleId);
                Long formId = shareRuleEntity.getFormId();
                Objects.requireNonNull(shareRuleEntity);
                Integer formNum = formNumMap.get(formId);
                if (Objects.nonNull(formNum) && formNum > 5) {
                    Map<String, Integer> userNumMap = formUserNumMap.get(formId);
                    if (MapUtils.isEmpty(userNumMap)) {
                        formUserNumMap.put(formId, new HashMap<>());
                        userNumMap = formUserNumMap.get(formId);
                    }
                    for (String needAddUserId : needAddUserIds) {
                        userNumMap.put(needAddUserId, 1 + userNumMap.getOrDefault(needAddUserId, 0));
                    }
                }

                for (String userId : needAddUserIds) {
                    SharePermissionSetUserEntity entity = new SharePermissionSetUserEntity(null, corpid, shareRuleEntity.getAppId(), ruleId, formId, userId, 0);
                    allNeedAddUsers.add(entity);
                }
            }
            if (!needDeleteUserIds.isEmpty()) {
                for (SharePermissionSetUserEntity entity : oldRuleId2UsersMap.get(ruleId)) {
                    if (needDeleteUserIds.contains(entity.getUserId())) {
                        allNeedDeleteIds.add(entity.getId());
                    }
                }
            }
        }
        validateUserRule4Recalculate(corpid, formUserNumMap);
    }

    /**
     * 获取数据库中（之前计算的）人员参数
     * @param corpid
     * @param oldRuleId2UsersMap
     */
    private void setOldUserParams(String corpid, Map<Long, List<SharePermissionSetUserEntity>> oldRuleId2UsersMap) {
        Map<String,Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("del", 0);
        List<SharePermissionSetUserEntity> sharePermissionSetUserEntities = sharePermissionSetUserModel.findEntitys(param);
        for (SharePermissionSetUserEntity entity : sharePermissionSetUserEntities) {
            Long shareRuleId = entity.getShareRuleId();
            if (Objects.isNull(oldRuleId2UsersMap.get(shareRuleId))) {
                oldRuleId2UsersMap.put(shareRuleId, new ArrayList<>());
            }
            oldRuleId2UsersMap.get(shareRuleId)
                    .add(entity);
        }
    }

    /**
     * 获取新计算得到的人员参数 以及其他所需（shareRuleMap、formNumMap、newRuleId2UsersMap）
     * @param corpid
     * @param shareRuleMap
     * @param formNumMap 表单-表单数量Map
     * @param newRuleId2UsersMap 新计算得到的 ruleId-UserMap
     */
    private void setNewUserParams(String corpid,  Map<Long, ShareRuleEntity> shareRuleMap,
                                  Map<Long, Integer> formNumMap, Map<Long, Set<String>> newRuleId2UsersMap) {
        Map<String, Object> param = new HashMap<>();
        param.put("corpid", corpid);
        param.put("del", 0);
        List<ShareRuleEntity> shareRuleEntities = shareRuleModel.findEntitys(param);
        if (shareRuleEntities.isEmpty()) {
            return;
        }

        Set<Integer> allRoleIdIn = new HashSet<>();
        Set<Long> allDeptIdIn = new HashSet<>();

        Map<Long, Set<Integer>> ruleId2roleIdsMap = new HashMap<>();
        Map<Long, Set<Long>> ruleId2deptIdsMap = new HashMap<>();
        for (ShareRuleEntity shareRuleEntity : shareRuleEntities) {
            Long ruleId = shareRuleEntity.getId();

            formNumMap.put(shareRuleEntity.getFormId(), 1 + formNumMap.getOrDefault(shareRuleEntity.getFormId(), 0));
            shareRuleMap.put(ruleId, shareRuleEntity);

            //获取ruleId -> (roleIds 、 deptIds、userIds) 的映射
            if (!shareRuleEntity.getAuthorityRole().isEmpty()) {
                List<String> roleIds = JSONObject.parseArray(shareRuleEntity.getAuthorityRole().toJSONString(), String.class);
                Set<Integer> roleIdIn = new HashSet<>();
                roleIds.stream().map(Integer::valueOf).forEach(integer -> {
                    roleIdIn.add(integer);
                    allRoleIdIn.add(integer);
                });
                ruleId2roleIdsMap.put(ruleId, roleIdIn);
            }
            if (!shareRuleEntity.getAuthorityDept().isEmpty()) {
                List<String> deptIds = JSONObject.parseArray(shareRuleEntity.getAuthorityDept().toJSONString(), String.class);

                Set<Long> deptIdIn = new HashSet<>();
                deptIds.stream().map(Long::valueOf).forEach(aLong -> {
                    deptIdIn.add(aLong);
                    allDeptIdIn.add(aLong);
                });
                ruleId2deptIdsMap.put(ruleId, deptIdIn);
            }
            if (!shareRuleEntity.getAuthorityUser().isEmpty()) {
                Set<String> userIdIn = new HashSet<>();
                List<String> userIds = JSONObject.parseArray(shareRuleEntity.getAuthorityUser().toJSONString(), String.class);
                userIdIn.addAll(userIds);
                newRuleId2UsersMap.put(ruleId, userIdIn);
            } else if (!newRuleId2UsersMap.containsKey(ruleId)) {
                newRuleId2UsersMap.put(ruleId, new HashSet<>());
            }
        }

        //获取部门Id、角色Id -> userIds 的映射
        Map<Integer, List<String>> roleId2UserIdsMap =  getRoleId2UserIdsMap(corpid, allRoleIdIn);
        Map<Long, List<String>> deptId2UserIdsMap = getDeptId2UserIdsMap(corpid, allDeptIdIn);

        // 重算后的 ruleId--> users 的映射
        for (Map.Entry<Long, Set<String>> entry : newRuleId2UsersMap.entrySet()) {
            Long ruleId = entry.getKey();
            Set<String> userIds = entry.getValue();
            if (ruleId2roleIdsMap.containsKey(ruleId)) {
                for (Integer roleId : ruleId2roleIdsMap.get(ruleId)) {
                    userIds.addAll(roleId2UserIdsMap.getOrDefault(roleId, new ArrayList<>()));
                }
            }
            if (ruleId2deptIdsMap.containsKey(ruleId)) {
                for (Long deptId : ruleId2deptIdsMap.get(ruleId)) {
                    userIds.addAll(deptId2UserIdsMap.getOrDefault(deptId, new ArrayList<>()));
                }
            }
        }
    }

    /**
     * 获取部门Id 到人员的映射
     * @param corpid
     * @param deptIdIn
     * @return
     */
    private Map<Long, List<String>> getDeptId2UserIdsMap(String corpid, Set<Long> deptIdIn) {
        Map<Long, List<String>> res = new HashMap<>();
        if (CollectionUtils.isEmpty(deptIdIn)) {
            return res;
        }
        List<UserDepartmentEntity> userDepEntitiesByDepIds = userModel.getUserDepEntitiesByDepIds(corpid, new ArrayList<>(deptIdIn));
        for (UserDepartmentEntity entity : userDepEntitiesByDepIds) {
            if (Objects.isNull(res.get(entity.getDepartmentId()))) {
                res.put(entity.getDepartmentId(), new ArrayList<>());
            }
            res.get(entity.getDepartmentId())
                    .add(entity.getUserId());
        }
        return res;
    }

    /**
     * 获取角色Id 到人员的映射
     * @param corpid
     * @param roleIdIn
     * @return
     */
    private Map<Integer, List<String>> getRoleId2UserIdsMap(String corpid, Set<Integer> roleIdIn) {
        Map<Integer, List<String>> res = new HashMap<>();
        if (CollectionUtils.isEmpty(roleIdIn)) {
            return res;
        }
        List<UserEntity> usersByRoleId = userModel.getUsersByRoleId(corpid, new ArrayList<>(roleIdIn));
        for (UserEntity userEntity : usersByRoleId) {
            if (userEntity.getRoleIds().isEmpty()) {
                continue;
            }
            String roleIdsStr = userEntity.getRoleIds();
            String[] roleIds = StringUtil.filterDoubleQuotes(roleIdsStr.substring(1, roleIdsStr.length() - 1)).split("\\|");
            for (String roleId : roleIds) {
                int intRoleId = Integer.parseInt(roleId);
                if (roleIdIn.contains(intRoleId)) {
                    if (Objects.isNull(res.get(intRoleId))) {
                        res.put(intRoleId, new ArrayList<>());
                    }
                    res.get(intRoleId).add(userEntity.getUserId());
                }
            }
        }
        return res;
    }


    /**
     * 获取需要插入的ShareRuleEntity + userIdList
     *
     * @param userIdList
     * @param sharePermissionSaveDTO
     * @return
     */
    private ShareRuleEntity getShareRuleEntityAndParam(Set<String> userIdList, SharePermissionSaveDTO sharePermissionSaveDTO) {
        List<OptionalRangePojo> authorityList = sharePermissionSaveDTO.getAuthority();
        JSONArray authorityRole = new JSONArray();
        JSONArray authorityDept = new JSONArray();
        JSONArray authorityUser = new JSONArray();
        List<Integer> roleIdIn = new ArrayList<>();
        List<Long> deptIdIn = new ArrayList<>();

        //区分部门、角色、人员
        for (OptionalRangePojo pojo : authorityList) {
            String property = pojo.getProperty();
            String id = pojo.getId();
            if (Objects.equals(property, "role")) {
                roleIdIn.add(Integer.valueOf(id));
                authorityRole.add(id);
            } else if (Objects.equals(property, "dept")) {
                deptIdIn.add(Long.valueOf(id));
                authorityDept.add(id);
            } else if (Objects.equals(property, "user")) {
                userIdList.add(id);
                authorityUser.add(id);
            }
        }
        //获取部门、角色下的人员
        if (CollectionUtils.isNotEmpty(roleIdIn)) {
            List<String> userIdsByRoles = userModel.getUserIdsByRoles(sharePermissionSaveDTO.getCorpid(), roleIdIn);
            userIdList.addAll(userIdsByRoles);
        }
        if (CollectionUtils.isNotEmpty(deptIdIn)) {
            List<String> userIdsByDep = userModel.getUserIdsRecursionDep(deptIdIn, sharePermissionSaveDTO.getCorpid());
            userIdList.addAll(userIdsByDep);
        }

        return new ShareRuleEntity(sharePermissionSaveDTO.getId(), sharePermissionSaveDTO.getCorpid(),
                sharePermissionSaveDTO.getAppId(), sharePermissionSaveDTO.getSaasMark(), sharePermissionSaveDTO.getBusinessType(), sharePermissionSaveDTO.getName(),
                sharePermissionSaveDTO.getFormId(), (JSONObject) JSON.toJSON(sharePermissionSaveDTO.getCondition()), (JSONArray) JSON.toJSON(sharePermissionSaveDTO.getAuthority()),
                authorityRole, authorityDept, authorityUser, sharePermissionSaveDTO.getPermission(), DelEnum.NORMAL.getDel());
    }

    /**
     * 重算中的，校验规则 3 同一员工、同一业务对象 上限5条规则 (注，这边循环中有Sql查询，但次数应该不多)
     * @param corpid
     * @param formUserNumMap
     * @throws XbbException
     */
    private void validateUserRule4Recalculate(String corpid, Map<Long, Map<String, Integer>> formUserNumMap) throws XbbException {
        if (MapUtils.isEmpty(formUserNumMap)) {
            return;
        }
        Set<String> extraUsers = new HashSet<>();
        boolean isConform = true;
        Long formId = 0L;
        for (Map.Entry<Long, Map<String, Integer>> longMapEntry : formUserNumMap.entrySet()) {
            formId = longMapEntry.getKey();
            Map<String, Integer> userNumMap = longMapEntry.getValue();
            Set<String> addUserIds = userNumMap.keySet();
            for (String addUserId : addUserIds) {
                if (userNumMap.get(addUserId) > 5) {
                    extraUsers.add(addUserId);
                    isConform = false;
                }
            }
            List<SharePermissionSetUserEntity> entitysByUsers = sharePermissionSetUserModel.getEntitysByUsersAndForm(corpid, formId, new ArrayList(addUserIds));
            if (CollectionUtils.isNotEmpty(entitysByUsers)) {
                for (SharePermissionSetUserEntity setUserEntity : entitysByUsers) {
                    userNumMap.put(setUserEntity.getUserId(), 1 + userNumMap.getOrDefault(setUserEntity.getUserId(), 0));
                    if (userNumMap.get(setUserEntity.getUserId()) > 5) {
                        extraUsers.add(setUserEntity.getUserId());
                        isConform = false;
                    }
                }
            }
            //只支持一张表单的报错
            if (!isConform) {
                break;
            }
        }
        if (!isConform) {
            List<UserEntity> entitysByUserIds = userModel.findEntitysByUserIds(new ArrayList<>(extraUsers), corpid);
            List<String> userNameList = entitysByUserIds.stream().map(UserEntity::getName).collect(Collectors.toList());
            String userStr = StringUtils.join(userNameList, '、');
            Map<Long, String> nameMap = formHelp.getNameMap(corpid, Collections.singletonList(formId));
            throw new XbbException(SharePermissionErrorCodeEnum.API_ERROR_345006, SharePermissionErrorCodeEnum.API_ERROR_345006.getMsg(), userStr, nameMap.getOrDefault(formId, ""));
        }
    }

    /**
     * 校验规则 3 同一员工、同一业务对象 上限5条规则
     *
     * @param corpid
     * @param formId
     * @param userIdList 表单授权员工
     * @param ruleId
     * @throws XbbException
     */
    private void validateUserRule(String corpid, Long formId, List<String> userIdList, Long ruleId) throws XbbException {
        // 查询该表单的，新增的那些人的数据， 若>5 则与规则不符
        List<SharePermissionSetUserEntity> entitysByUsers = sharePermissionSetUserModel.getEntitysByUsersAndForm(corpid, formId, userIdList);
        Map<String, Integer> userNumMap = new HashMap<>();
        List<String> userIds = new ArrayList<>();
        boolean isConform = true;
        for (SharePermissionSetUserEntity entity : entitysByUsers) {
            if (Objects.equals(entity.getShareRuleId(), ruleId)) {
                continue;
            }
            userNumMap.put(entity.getUserId(), 1 + userNumMap.getOrDefault(entity.getUserId(), 0));
            if (userNumMap.get(entity.getUserId()) >= 5) {
                isConform = false;
                userIds.add(entity.getUserId());
            }
        }
        if (!isConform) {
            List<UserEntity> entitysByUserIds = userModel.findEntitysByUserIds(userIds, corpid);
            List<String> userNameList = entitysByUserIds.stream().map(UserEntity::getName).collect(Collectors.toList());
            String userStr = StringUtils.join(userNameList, '、');
            Map<Long, String> nameMap = formHelp.getNameMap(corpid, Collections.singletonList(formId));
            throw new XbbException(SharePermissionErrorCodeEnum.API_ERROR_345003, SharePermissionErrorCodeEnum.API_ERROR_345003.getMsg(), userStr, nameMap.getOrDefault(formId, ""));
        }
    }

    /**
     * 校验规则 1、2： 公司总规则数20条 + 同一表单最多 formLimit 条（默认10条）
     *
     * @param corpid
     * @param formId
     * @throws XbbException
     */
    private void validateCompanyAndFormRule(String corpid, Long formId, boolean isAdd) throws XbbException {
        Integer formLimit = getFormLimit(corpid);
        if (formLimit <= 10 && isAdd) {
            //校验1. 检查 公司总规则数20条（formLimit>10 则失效）
            Integer allRuleCount = shareRuleModel.getAllRuleCount(corpid);
            if (allRuleCount >= 20) {
                throw new XbbException(SharePermissionErrorCodeEnum.API_ERROR_345001);
            }
        }
        //校验2. 同一表单最多 formLimit 条
        Integer countByForm = shareRuleModel.getCountByForm(corpid, formId);
        if (isAdd) {
            countByForm++;
        }
        if (countByForm > formLimit) {
            String addOrUpdate = isAdd ? I18nMessageUtil.getMessage(I18nStringConstant.ADD_TAG) : I18nMessageUtil.getMessage(I18nStringConstant.UPDATE_TAG);
            throw new XbbException(SharePermissionErrorCodeEnum.API_ERROR_345002, SharePermissionErrorCodeEnum.API_ERROR_345002.getMsg(), addOrUpdate, formLimit.toString());
        }
    }

    /**
     * 获取单个表单规则限制数量
     *
     * @param corpid
     * @return
     */
    private Integer getFormLimit(String corpid) {
        CompanyConfigEntity byConfigAlias = companyConfigModel.getByConfigAlias(CompanyConfigEnum.SHARE_PERMISSION_LIMIT.getAlias(), corpid);
        Integer formLimit = 10;
        if (Objects.isNull(byConfigAlias)
                || StringUtil.isEmpty(byConfigAlias.getConfigValue())) {
            return formLimit;
        }
        return Integer.parseInt(byConfigAlias.getConfigValue());
    }
}
